package com.new4net.exe_stream.factory.impl;


import com.new4net.exe_stream.factory.ExecutionStatementFactory;
import com.new4net.exe_stream.instruction.impl.ExecutionInstruction;
import com.new4net.exe_stream.meta.ExecutionContext;
import com.new4net.exe_stream.meta.ExecutionStatement;
import com.new4net.exe_stream.meta.impl.SimpleExecutionContext;
import com.new4net.exe_stream.service.impl.SimpleExecutionInstructionService;
import com.new4net.exe_stream.meta.impl.SimpleExecutionStatement;
import com.new4net.exe_stream.service.*;
import com.new4net.exe_stream.service.impl.ConsoleExecutionLogService;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 业务追踪系统
 */
public class BusiTraceFactory implements ExecutionStatementFactory, TraceService {



    private DomainModelDiagram domainModelDiagram ;

    /**
     * 线程池 用于并行流 required
     */

    private ExecutorService executorService;

    /**
     * 业务追踪结果服务,如没有，则使用默认的控制台输出ConsoleBusiTraceResultService
     */
    private ExecutionLogService executionLogService;

    protected ExecutionInstructionService executionInstructionService;

    public BusiTraceFactory(ExecutorService executorService,
                            ExecutionLogService executionLogService) {


        this.executorService = executorService;
        if(executionLogService !=null){
            this.executionLogService = executionLogService;

        }else {
            this.executionLogService =new ConsoleExecutionLogService();
        }
        scanDomainModels();
        executionInstructionService =new SimpleExecutionInstructionService();



    }

    public static void main(String[] args) {
        BusiTraceFactory busiTraceFactory = new BusiTraceFactory(Executors.newCachedThreadPool(),null);

        for(int y=0;y<100;y++){
            long l = System.currentTimeMillis();
            ExecutionInstruction instruction =  busiTraceFactory.build("test")
                    ._then("test1",(a)->{
                        a.addParam("test1","wwffwf");
                        int i = 1/0;
                        return i;
                    })
                        ._catch((e,c)->{
                            c.addParam("test2","wwffwf");
                            int i = 5;
                            return i;
                        })
                    ._then("test2",(a)->{
                        a.addParam("test1","wwffwf");
                        int i = 1/0;
                        return i;
                    })
                        ._catch((e,c)->{
                            c.addParam("test2","wwffwf44");
                            int i = 5;
                            return i;
                        })
                    ._switch("判断i的大小")
                        ._if("大于3",c->((int)(c.getReturnVal()))>3,a->

                                {
                                    String s =  a.getParam("test2");
                                    System.out.println(s);
                                    a.addParam("xxx6666","9999");
                                    return 6;
                                }


                                )
                        ._else("否则",a->

                        {

                            a.addParam("xxx6666","8888");
                            return 7;
                        })
                        ._end()
                    ._end();
            long z = System.currentTimeMillis();
            System.out.println(z-l);
            int k =
                    instruction.execute();
            System.out.println(k);
            System.out.println(System.currentTimeMillis()-l);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }


    }


    @Override
    public ExecutionStatement<ExecutionInstruction> build(String modelName) {
        ExecutionContext executionContext = new SimpleExecutionContext(this.executorService
                ,this.executionLogService
                ,this.domainModelDiagram
                ,this.executionInstructionService);
        return new SimpleExecutionStatement(modelName,executionContext);
    }


    @Override
    public ExecutionInstructionService getExecutionInstructionService() {
        return executionInstructionService;
    }

    @Override
    public BusiFlowProcessDiagram traceBusiFlow(ExecutionStatement stmt) {
        return null;
    }

    @Override
    public BusiFlowProcessDiagram traceAllBusiFlow() {
        return null;
    }


    public void scanDomainModels() {

    }
}
